/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: fat file system
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2022-08-15     JasonHu           Port from xboot
 */

#ifndef __FAT_CONTROL_H__
#define __FAT_CONTROL_H__

#include "fat.h"

#define FAT_TABLE_CACHE_SIZE	(32)

/*
 * Information about a "mounted" FAT filesystem
 */
struct fatfs_control_t {
	/* FAT boot sector */
	struct fat_bootsec_t bsec;

	/* Underlying block device */
	// NX_Device * bdev;
	NX_Solt bdev;

	/* Frequently required boot sector info */
	NX_U16 bytes_per_sector;
	NX_U8 sectors_per_cluster;
	NX_U8 number_of_fat;
	NX_U32 bytes_per_cluster;
	NX_U32 total_sectors;

	/* Derived FAT info */
	NX_U32 first_fat_sector;
	NX_U32 sectors_per_fat;
	NX_U32 fat_sectors;

	NX_U32 first_root_sector;
	NX_U32 root_sectors;
	NX_U32 first_root_cluster;

	NX_U32 first_data_sector;
	NX_U32 data_sectors;
	NX_U32 data_clusters;

	/* FAT type */
	enum fat_type_t type;

	/* FAT sector cache */
	// NX_Mutex fat_cache_lock;
	NX_Solt fat_cache_lock;
	NX_U32 fat_cache_victim;
	NX_Bool fat_cache_dirty[FAT_TABLE_CACHE_SIZE];
	NX_U32 fat_cache_num[FAT_TABLE_CACHE_SIZE];
	NX_U8 * fat_cache_buf;
};

NX_TimeStamp fatfs_pack_timestamp(NX_U32 year, NX_U32 mon, NX_U32 day, NX_U32 hour, NX_U32 min, NX_U32 sec);
void fatfs_current_timestamp(NX_U32 * year, NX_U32 * mon, NX_U32 * day, NX_U32 * hour, NX_U32 * min, NX_U32 * sec);
void fatfs_timestamp(NX_TimeStamp * d, NX_U32 * year, NX_U32 * mon, NX_U32 * day, NX_U32 * hour, NX_U32 * min, NX_U32 * sec);
NX_Bool fatfs_control_valid_cluster(struct fatfs_control_t * ctrl, NX_U32 clust);
int fatfs_control_nth_cluster(struct fatfs_control_t * ctrl, NX_U32 clust, NX_U32 pos, NX_U32 * next);
int fatfs_control_set_last_cluster(struct fatfs_control_t * ctrl, NX_U32 clust);
int fatfs_control_alloc_first_cluster(struct fatfs_control_t * ctrl, NX_U32 * newclust);
int fatfs_control_append_free_cluster(struct fatfs_control_t * ctrl, NX_U32 clust, NX_U32 * newclust);
int fatfs_control_truncate_clusters(struct fatfs_control_t * ctrl, NX_U32 clust);
int fatfs_control_sync(struct fatfs_control_t * ctrl);
// int fatfs_control_init(struct fatfs_control_t * ctrl, NX_Device * bdev);
int fatfs_control_init(struct fatfs_control_t * ctrl, NX_Solt bdev);
int fatfs_control_exit(struct fatfs_control_t * ctrl);

#endif /* __FAT_CONTROL_H__ */
